import { reroute } from "./reroute.js";



function urlReroute() {
    reroute([], arguments) //会根据路径加载不同的应用
}

// 监听路由变化, 如果路由变化了重新加载应用  
window.addEventListener('hashchange',urlReroute)
window.addEventListener('popstate',urlReroute)

// 用户可能还会绑定自己的路由事件，自己的路由时间也会通过addEventListener去监听的，那么就需要重写addEventListener方法
// 当我们应用切换后还需要处理原来的方法，需要在应用切换之后执行
const originalAddEventListener = window.addEventListener;
const originalRemoveEventListener = window.removeEventListener;
export const routingEventsListeningTo = ["hashchange", "popstate"];
const capturedEventListeners = { // 存储hashchang和popstate注册的方法，后续挂载的事件先暂存起来
    hashchange: [],
    popstate: []//当应用切换完成后可以调用
}
window.addEventListener = function(eventName, fn) {
    if (routingEventsListeningTo.indexOf(eventName) >= 0 && !capturedEventListeners[eventName].some(listener => listener == fn)) {
        capturedEventListeners[eventName].push(fn);
        return;
    }
    return originalAddEventListener.apply(this, arguments);
}
window.removeEventListener = function(eventName, listenerFn) {
    if (routingEventsListeningTo.indexOf(eventName) >= 0) {
        capturedEventListeners[eventName] = capturedEventListeners[
            eventName
        ].filter((fn) => fn !== listenerFn);
        return;
    }
    return originalRemoveEventListener.apply(this, arguments);
};

function patchedUpdateState(updateState, methodName) {
    return function() {
        const urlBefore = window.location.href;
        const result = updateState.apply(this, arguments);//调用切换方法
        const urlAfter = window.location.href; 
        if (urlBefore !== urlAfter) {
            // 重新加载应用，传入事件源
            urlReroute(new PopStateEvent('popstate', { state }));
        }
        return result;
    }
}
// 重写pushState 和 repalceState方法
window.history.pushState = patchedUpdateState(window.history.pushState, 'pushState');
window.history.replaceState = patchedUpdateState(window.history.replaceState, 'replaceState');

// 在子应用加载完毕后调用此方法，执行拦截的逻辑（保证子应用加载完后执行）
export function callCapturedEventListeners(eventArguments) {
    if (eventArguments) {
        const eventType = eventArguments[0].type;
        if (routingEventsListeningTo.indexOf(eventType) >= 0) {
            capturedEventListeners[eventType].forEach((listener) => {
                listener.apply(this, eventArguments);
            });
        }
    }
}
// 为了保证应用加载逻辑最先被处理，我们对路由的一系列的方法进行重写，确保加载应用的逻辑最先被调用，其次手动派发事件
